package com.ft.oa.service.development.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ft.oa.domain.approval.ApplyForApproval;
import com.ft.oa.domain.dev.DevAllocateAccept;
import com.ft.oa.domain.development.*;
import com.ft.oa.domain.dto.ApiResult;
import com.ft.oa.domain.dto.knowledgeBase.AttachmentDto;
import com.ft.oa.domain.dto.sys.SecurityUser;
import com.ft.oa.domain.project.ExecProject;
import com.ft.oa.domain.project.ExecProjectContract;
import com.ft.oa.domain.sys.SysUser;
import com.ft.oa.enums.DirectoryTypeEnum;
import com.ft.oa.enums.ManagerEnum;
import com.ft.oa.mapper.customer.ExecProjectContractMapper;
import com.ft.oa.mapper.dev.DevAllocateAcceptMapper;
import com.ft.oa.mapper.development.*;
import com.ft.oa.mapper.industrysMapper.DevNeedAnalyseMapper;
import com.ft.oa.mapper.project.ExecProjectMapper;
import com.ft.oa.service.approval.ApplyForApprovalService;
import com.ft.oa.service.development.DevExecService;
import com.ft.oa.service.knowledgeBase.DirectoryService;
import com.ft.oa.service.sys.SysUserService;
import com.ft.oa.utils.SecurityUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class DevExecServiceImpl implements DevExecService {

    @Resource
    private DevNeedMapper devNeedMapper;
    @Resource
    private DevAllocateMapper devAllocateMapper;
    @Resource
    private DevAllocateStaffMapper devAllocateStaffMapper;
    @Resource
    private DevNeedInfoMapper devNeedInfoMapper;
    @Resource
    private DevAllocateStaffMapper allocateStaffMapper;
    @Resource
    private DevNeedIssueMapper devNeedIssueMapper;
    @Resource
    private SysUserService sysUserService;
    @Resource
    private ApplyForApprovalService applyForApprovalService;
    @Resource
    private DevNeedAnalyseMapper devNeedAnalyseMapper;
    @Resource
    private ExecProjectMapper execProjectMapper;
    @Resource
    private NeedContractMapper needContractMapper;
    @Resource
    private ExecProjectContractMapper execProjectContractMapper;

    @Resource
    private DirectoryService directoryService;

    @Resource
    private DevAllocateAcceptMapper devAllocateAcceptMapper;

    @Override
    public ApiResult approverList() {

        List<SysUser> sysUsers = sysUserService.listAll();

        return ApiResult.successWithData(sysUsers);
    }

    @Override
    public ApiResult copyerList() {
        List<SysUser> sysUsers = sysUserService.listAll();

        return ApiResult.successWithData(sysUsers);
    }


    @Override
    public Page<DevNeedIssue> page(DevNeedIssue condition) {
        QueryWrapper<DevNeedIssue> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("create_time");
        wrapper.lambda()
                .ne(DevNeedIssue::getDataState, 1)
                .eq(ManagerEnum.GENERAL.toString().equals(SecurityUtils.getCurrentUser().getManager()), DevNeedIssue::getCreator,SecurityUtils.getCurrentUser().getId())
                .eq(condition.getProductCategoryId() != null, DevNeedIssue::getProductCategoryId, condition.getProductCategoryId())
                .eq(StringUtils.hasText(condition.getDevNeedCategory()), DevNeedIssue::getDevNeedCategory, condition.getDevNeedCategory())
                .eq(StringUtils.hasText(condition.getDevModel()), DevNeedIssue::getDevModel, condition.getDevModel())
                .eq(StringUtils.hasText(condition.getShuntDirection()), DevNeedIssue::getShuntDirection, condition.getShuntDirection())
                .ne(DevNeedIssue::getDataState,"2");

        Page<DevNeedIssue> page = new Page<>(condition.getPage(), condition.getSize());

        Page<DevNeedIssue> result = devNeedIssueMapper.selectPage(page, wrapper);

        return result;
    }

    @Override
    public Page<DevAllocate> allocatedPage(DevAllocate condition) {

        QueryWrapper<DevAllocate> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("project_approval_data", condition.getProjectApprovalData());
        wrapper.lambda()
                .ge(StringUtils.hasText(condition.getProjectApprovalDataLeft()), DevAllocate::getProjectApprovalData, condition.getProjectApprovalDataLeft())
                .le(StringUtils.hasText(condition.getProjectApprovalDataRight()), DevAllocate::getProjectApprovalData, condition.getProjectApprovalDataRight())
                .ge(StringUtils.hasText(condition.getPlanFinishDataLeft()), DevAllocate::getPlanFinishData, condition.getPlanFinishDataLeft())
                .le(StringUtils.hasText(condition.getPlanFinishDataRight()), DevAllocate::getPlanFinishData, condition.getPlanFinishDataRight())
                .eq(StringUtils.hasText(condition.getDevNeedCategory()), DevAllocate::getDevNeedCategory, condition.getDevNeedCategory())
                .eq(condition.getApprovalStatus() != null, DevAllocate::getApprovalStatus, condition.getApprovalStatus())
                .like(StringUtils.hasText(condition.getAllocateProjectManage()), DevAllocate::getAllocateProjectManage, condition.getAllocateProjectManage())
                .eq(condition.getIsAccept() != null, DevAllocate::getIsAccept, condition.getIsAccept())
                .ge(StringUtils.hasText(condition.getFinishDataLeft()), DevAllocate::getFinishData, condition.getFinishDataLeft())
                .le(StringUtils.hasText(condition.getFinishDataRight()), DevAllocate::getFinishData, condition.getFinishDataRight())
                .like(StringUtils.hasText(condition.getDevAllocateName()), DevAllocate::getDevAllocateName, condition.getDevAllocateName());

        Page<DevAllocate> page = new Page<>(condition.getPage(), condition.getSize());

        Page<DevAllocate> result = devAllocateMapper.selectPage(page, wrapper);

        result.getRecords().forEach(
                e -> {
                    //回填需求信息
                    DevNeedIssue issue = devNeedIssueMapper.selectById(e.getDevNeedIssueId());
                    e.injectNeedInfo(issue);
                    //项目参与人回填
                    QueryWrapper<DevAllocateStaff> staffQueryWrapper = new QueryWrapper<>();
                    staffQueryWrapper.lambda()
                            .eq(DevAllocateStaff::getDevAllocateId, e.getId());
                    List<DevAllocateStaff> staffs = allocateStaffMapper.selectList(staffQueryWrapper);
                    e.setStaffs(staffs);
                    if (e.getIsAccept() != null && e.getIsAccept() == 1) {
                        QueryWrapper<DevAllocateAccept> queryWrapper = new QueryWrapper<>();
                        queryWrapper.lambda()
                                .eq(DevAllocateAccept::getDevAllocateId, e.getId());
                        DevAllocateAccept devAllocateAccept = devAllocateAcceptMapper.selectOne(queryWrapper);
                        String attachmentRel = devAllocateAccept.getAttachmentRel();
                        devAllocateAccept.setAttachments(JSONObject.parseArray(attachmentRel, AttachmentDto.class));
                        e.setDevAllocateAccept(devAllocateAccept);
                    }else {
                        e.setDevAllocateAccept(new DevAllocateAccept());
                    }
                }
        );

        return result;
    }


    @Override
    @Transactional
    public ApiResult allocate(DevAllocate allocate) {

        DevNeedIssue devNeedIssue = devNeedIssueMapper.selectById(allocate.getDevNeedIssueId());

        if (devNeedIssue.getDataState() != 0) {
            return ApiResult.builder().code(20002).msg("分配失败，请联系管理员！").build();
        }

        allocate.setDevNeedIssueId(devNeedIssue.getId());
        allocate.setDevNeedNo(devNeedIssue.getDevNeedNo());
        allocate.setDevNeedCategory(devNeedIssue.getDevNeedCategory());
        allocate.setCreateTime(LocalDateTime.now());
        allocate.setIsAccept(0);
        //固定修改审核状态为通过
        allocate.setApprovalStatus(1);

        devAllocateMapper.insert(allocate);
        //保存参与人
        List<DevAllocateStaff> staffs = allocate.getStaffs();
        if (staffs != null && staffs.size() > 0) {
            staffs.forEach(
                    e -> {
                        e.setDevAllocateId(allocate.getId());
                        allocateStaffMapper.insert(e);
                    }
            );
        }
        //修改需求下发表状态
        LambdaUpdateChainWrapper<DevNeedIssue> wrapper = new LambdaUpdateChainWrapper<>(devNeedIssueMapper);
        boolean update = wrapper.eq(DevNeedIssue::getId, allocate.getDevNeedIssueId())
                .set(DevNeedIssue::getDataState, 2)
                .update();
        ////审批
        //List<Long> approverList = allocate.getApproverList();
        //if (CollectionUtils.isEmpty(approverList)) {
        //    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        //    return ApiResult.builder().code(20009).msg("审批人不能为空！").build();
        //} else {
        //    List<ApplyForApproval> collect = approverList.stream()
        //            .map(
        //                    e -> {
        //                        ApplyForApproval applyForApproval = new ApplyForApproval();
        //                        applyForApproval.setRelationId(allocate.getId());
        //                        applyForApproval.setRelationType(8);
        //                        applyForApproval.setUserId(e);
        //                        //回调信息
        //                        applyForApproval.setCallBack(true);
        //                        TaskMsg taskMsg = new TaskMsg();
        //                        taskMsg.setName("devNeedAllocateCallBackTask");
        //                        taskMsg.setType(2);
        //                        HashMap<String, Object> params = new HashMap<>();
        //                        params.put("issueId", devNeedIssue.getId());
        //                        taskMsg.setParams(params);
        //                        String json = JSONObject.toJSONString(taskMsg);
        //                        applyForApproval.setCallBackMsg(json);
        //
        //                        return applyForApproval;
        //                    }
        //            )
        //            .collect(Collectors.toList());
        //
        //    applyForApprovalService.addApproval(collect);
        //}
        ////抄送
        //List<Long> copyerList = allocate.getCopyerList();
        //if (!CollectionUtils.isEmpty(copyerList)) {
        //    List<ApplyForApproval> collect = copyerList.stream()
        //            .map(e -> {
        //                ApplyForApproval applyForApproval = new ApplyForApproval();
        //                applyForApproval.setRelationId(allocate.getId());
        //                applyForApproval.setRelationType(8);
        //                applyForApproval.setUserId(e);
        //                return applyForApproval;
        //            })
        //            .collect(Collectors.toList());
        //    applyForApprovalService.addCarbonCopy(collect);
        //}

        //添加审批人
        //项目审批开始
        if (allocate.getDevAllocateCheckList() !=null) {
            List<ApplyForApproval> devAllocateCheckList = allocate.getDevAllocateCheckList();
            //添加抄送人
            List<ApplyForApproval> devAllocateNoticeList = allocate.getDevAllocateNoticeList();
            if (CollectionUtils.isEmpty(devAllocateCheckList)) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ApiResult.builder().code(20009).msg("审批人不能为空！").build();
            } else {
                devAllocateCheckList.forEach(e -> {
                    e.setRelationId(allocate.getId());
                    //业务表编码
                    e.setRelationCode(allocate.getDevAllocateName());
                    /**
                     * 关联审批分类 1、合同审批 2、协同审批 3、投标审批  4、立项审批  5、验收审批
                     * 6、成本变更审批  7、进度变更审批  8、研发立项审批  9、采购审批
                     */
                    e.setRelationType(8);
                });
                applyForApprovalService.addApproval(devAllocateCheckList);
                devAllocateNoticeList.forEach(e -> {
                    e.setRelationId(allocate.getId());
                    //业务表编码
                    e.setRelationCode(allocate.getDevAllocateName());
                    /**
                     * 关联审批分类 1、合同审批 2、协同审批 3、投标审批  4、立项审批  5、验收审批
                     * 6、成本变更审批  7、进度变更审批  8、研发立项审批  9、采购审批
                     */
                    e.setRelationType(8);
                });
                applyForApprovalService.addCarbonCopy(devAllocateNoticeList);
            }
        }
        return ApiResult.simpleSuccess();
    }

    /*
     * 查看未分配详情
     * */
    @Override
    public Map devNeedIssueDetail(Long id) {
        Map<String, Object> map = new HashMap<>();
        //查询基本信息/需求下发
        DevNeedIssue devNeedIssue = devNeedIssueMapper.selectById(id);
        map.put("issue", devNeedIssue);
        //查询立项项目信息/需求信息/研发需求信息/需求分析
        QueryWrapper<DevNeed> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(DevNeed::getIssueId, id);
        List<DevNeed> devNeedList = devNeedMapper.selectList(queryWrapper);
        //研发需求信息
        devNeedList.forEach(
                e -> {
                    //判断合同是否是手动输入的
                    if (e.getProjectId() != null) {
                        //如果选择的，根据exe-project表查询
                        //查询录入的表
                        ExecProject execProject = execProjectMapper.selectById(e.getProjectId());

                        QueryWrapper<ExecProjectContract> wrapper = new QueryWrapper<>();
                        wrapper.lambda().eq(ExecProjectContract::getProjectNumber, execProject.getProjectNumber())
                                .eq(ExecProjectContract::getDel, 0);
                        List<ExecProjectContract> list = execProjectContractMapper.selectList(wrapper);
                        List<NeedContract> collect = list.stream()
                                .map(
                                        es -> {
                                            NeedContract needContract = new NeedContract();
                                            needContract.setContactName(es.getContractName());
                                            needContract.setContractNo(es.getContractNo());
                                            needContract.setDeliveryDate(es.getDeliveryDate());
                                            needContract.setId(es.getId());
                                            needContract.setNeedId(es.getRelationId());
                                            needContract.setAttachments(JSONObject.parseArray(es.getAchment(), AttachmentDto.class));
                                            needContract.setProjectName(e.getProjectName());
                                            return needContract;
                                        }
                                )
                                .collect(Collectors.toList());
                        e.setNeedContractList(collect);
                    } else {
                        QueryWrapper<NeedContract> wrapper = new QueryWrapper<>();
                        wrapper.lambda()
                                .eq(NeedContract::getNeedId, e.getId())
                                .eq(NeedContract::getDel, false);
                        List<NeedContract> list = needContractMapper.selectList(wrapper);
                        list.forEach(
                                an -> {
                                    an.setProjectName(e.getProjectName());
                                    an.setAttachments(JSONObject.parseArray(an.getAttachment(), AttachmentDto.class));
                                }
                        );
                        e.setNeedContractList(list);
                    }
                    //回填研发需求
                    QueryWrapper<DevNeedInfo> infosQueryWrapper = new QueryWrapper<>();
                    infosQueryWrapper.lambda().eq(DevNeedInfo::getDevNeedId, e.getId());
                    List<DevNeedInfo> infos = devNeedInfoMapper.selectList(infosQueryWrapper);
                    e.setInfos(infos);
                    //回填需求分析
                    QueryWrapper<NeedAnalyse> analysesQueryWrapper = new QueryWrapper<>();
                    analysesQueryWrapper.lambda().eq(NeedAnalyse::getNeedId, e.getId()).eq(NeedAnalyse::getState, 0);
                    List<NeedAnalyse> analyses = devNeedAnalyseMapper.selectList(analysesQueryWrapper);
                    analyses.forEach(
                            an -> {
                                an.setChargePersonName(e.getChargePersonName());
                                an.setAttachments(JSONObject.parseArray(an.getAttachmentRel(), AttachmentDto.class));
                            }
                    );
                    e.setAnalyses(analyses);

                }
        );
        map.put("devNeed", devNeedList);
        return map;
    }

    @Override
    public Map devNeedAllocateDetail(Long id) {
        Map<String, Object> map = new HashMap<>();
        //查询基本信息/需求下发
        DevAllocate devAllocate = devAllocateMapper.selectById(id);
        if (devAllocate != null) {
            QueryWrapper<DevAllocateStaff> staff = new QueryWrapper<>();
            staff.lambda().eq(DevAllocateStaff::getDevAllocateId, devAllocate.getId());
            List<DevAllocateStaff> devAllocateStaffList = devAllocateStaffMapper.selectList(staff);
            devAllocate.setStaffs(devAllocateStaffList);
            //审批人员列表
            List<ApplyForApproval> devAllocateCheckList = applyForApprovalService.selectApprovalUser(id, 8);
            devAllocate.setDevAllocateCheckList(devAllocateCheckList);
            //抄送人员列表
            List<ApplyForApproval> devAllocateNoticeList = applyForApprovalService.selectCopyUser(id, 8);
            devAllocate.setDevAllocateNoticeList(devAllocateNoticeList);
            map.put("allocate", devAllocate);

            QueryWrapper<DevNeedIssue> dWrapper = new QueryWrapper<>();
            dWrapper.lambda().eq(DevNeedIssue::getId, devAllocate.getDevNeedIssueId());
            List<DevNeedIssue> devNeedIssueList = devNeedIssueMapper.selectList(dWrapper);
            map.put("issue", devNeedIssueList);

            //查询立项项目信息/需求信息/研发需求信息/需求分析
            QueryWrapper<DevNeed> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(DevNeed::getIssueId, devAllocate.getDevNeedIssueId());
            List<DevNeed> devNeedList = devNeedMapper.selectList(queryWrapper);
            //研发需求信息
            devNeedList.forEach(
                    e -> {
                        //判断合同是否是手动输入的
                        if (e.getProjectId() != null) {
                            //如果选择的，根据exe-project表查询
                            //查询录入的表
                            ExecProject execProject = execProjectMapper.selectById(e.getProjectId());

                            QueryWrapper<ExecProjectContract> wrapper = new QueryWrapper<>();
                            wrapper.lambda().eq(ExecProjectContract::getProjectNumber, execProject.getProjectNumber())
                                    .eq(ExecProjectContract::getDel, 0);
                            List<ExecProjectContract> list = execProjectContractMapper.selectList(wrapper);
                            List<NeedContract> collect = list.stream()
                                    .map(
                                            es -> {
                                                NeedContract needContract = new NeedContract();
                                                needContract.setContactName(es.getContractName());
                                                needContract.setContractNo(es.getContractNo());
                                                needContract.setDeliveryDate(es.getDeliveryDate());
                                                needContract.setId(es.getId());
                                                needContract.setNeedId(es.getRelationId());
                                                needContract.setAttachments(JSONObject.parseArray(es.getAchment(), AttachmentDto.class));
                                                needContract.setProjectName(e.getProjectName());
                                                return needContract;
                                            }
                                    )
                                    .collect(Collectors.toList());
                            e.setNeedContractList(collect);
                        } else {
                            QueryWrapper<NeedContract> wrapper = new QueryWrapper<>();
                            wrapper.lambda()
                                    .eq(NeedContract::getNeedId, e.getId())
                                    .eq(NeedContract::getDel, false);
                            List<NeedContract> list = needContractMapper.selectList(wrapper);
                            list.forEach(
                                    an -> {
                                        an.setProjectName(e.getProjectName());
                                        an.setAttachments(JSONObject.parseArray(an.getAttachment(), AttachmentDto.class));
                                    }
                            );
                            e.setNeedContractList(list);
                        }
                        //回填研发需求
                        QueryWrapper<DevNeedInfo> infosQueryWrapper = new QueryWrapper<>();
                        infosQueryWrapper.lambda().eq(DevNeedInfo::getDevNeedId, e.getId());
                        List<DevNeedInfo> infos = devNeedInfoMapper.selectList(infosQueryWrapper);
                        e.setInfos(infos);
                        //回填需求分析
                        QueryWrapper<NeedAnalyse> analysesQueryWrapper = new QueryWrapper<>();
                        analysesQueryWrapper.lambda().eq(NeedAnalyse::getNeedId, e.getId()).eq(NeedAnalyse::getState, 0);
                        List<NeedAnalyse> analyses = devNeedAnalyseMapper.selectList(analysesQueryWrapper);
                        analyses.forEach(
                                an -> {
                                    an.setChargePersonName(e.getChargePersonName());
                                    an.setAttachments(JSONObject.parseArray(an.getAttachmentRel(), AttachmentDto.class));
                                }
                        );
                        e.setAnalyses(analyses);

                    }
            );
            map.put("devNeed", devNeedList);

        }


        return map;
    }

    @Override
    public ApiResult devNeedAllocateAccept(DevAllocateAccept devAllocateAccept) {
        QueryWrapper<DevAllocateAccept> daaQueryWrapper = new QueryWrapper<>();
        daaQueryWrapper.lambda().eq(DevAllocateAccept::getDevAllocateId, devAllocateAccept.getDevAllocateId());
        DevAllocateAccept devAllocateAcceptQ = devAllocateAcceptMapper.selectOne(daaQueryWrapper);
        if( null==devAllocateAcceptQ ){
            SecurityUser currentUser = SecurityUtils.getCurrentUser();
            devAllocateAccept.setSubmitId(currentUser.getId());
            devAllocateAccept.setSubmitUser(currentUser.getUsername());
            devAllocateAccept.setCreateTime(LocalDateTime.now());
            devAllocateAcceptMapper.insert(devAllocateAccept);
        }else{
            devAllocateAcceptQ.setAcceptResult(devAllocateAccept.getAcceptResult());
            devAllocateAcceptQ.setScore(devAllocateAccept.getScore());
            devAllocateAcceptQ.setUpdateTime(LocalDateTime.now());
            devAllocateAcceptMapper.updateById(devAllocateAcceptQ);
        }
        System.out.println("123456");




        DevAllocate devAllocate = devAllocateMapper.selectById(devAllocateAccept.getDevAllocateId());
        if (devAllocateAccept.getAttachments() != null && devAllocateAccept.getAttachments().size() > 0) {
            String attachmentRel = JSONArray.toJSONString(devAllocateAccept.getAttachments());
            devAllocateAccept.setAttachmentRel(attachmentRel);
            directoryService.saveProAttachment(
                    devAllocateAccept.getAttachments(),
                    DirectoryTypeEnum.DEV_ALLOCATE_ACCEPT.getCode(),
                    devAllocateAccept.getId().toString(),
                    "1",
                    devAllocateAccept.getDevAllocateName()
            );

        }
        devAllocateAcceptMapper.updateById(devAllocateAccept);
        devAllocate.setIsAccept(1);
        Date date = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = formatter.format(date);
        devAllocate.setFinishData(dateString);
        devAllocateMapper.updateById(devAllocate);
        return ApiResult.simpleSuccess();
    }

}
